package top.hymsk.ecommerce.init;

import org.elasticsearch.action.admin.indices.delete.DeleteIndexRequest;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.client.indices.CreateIndexRequest;
import org.elasticsearch.client.indices.GetIndexRequest;
import org.elasticsearch.common.lucene.search.function.CombineFunction;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.index.query.functionscore.FunctionScoreQueryBuilder;
import org.elasticsearch.index.query.functionscore.ScoreFunctionBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import top.hymsk.ecommerce.dao.elasticsearch.ESConnection;
import top.hymsk.ecommerce.dao.elasticsearch.ElasticSearchMapper;
import top.hymsk.ecommerce.dao.mapper.ElasticSearchInitProductMapper;
import top.hymsk.ecommerce.pojo.PO.es.ElasticSearchProductPO;

import java.io.IOException;
import java.util.List;

@SpringBootTest
class ESInit {
    static String indexCreateString = "{\n" +
            "\t\"mappings\": {\n" +
            "    \"properties\": {\n" +
            "      \"productId\": {\n" +
            "        \"type\": \"keyword\"\n" +
            "      },\n" +
            "      \"all\":{\n" +
            "        \"type\": \"text\",\n" +
            "        \"analyzer\": \"ik_smart\"\n" +
            "      },\n" +
            "      \"title\": {\n" +
            "        \"type\": \"text\",\n" +
            "        \"analyzer\": \"ik_smart\", \n" +
            "        \"copy_to\": \"all\"\n" +
            "      },\n" +
            "      \"price\":{\n" +
            "        \"type\": \"double\"\n" +
            "      },\n" +
            "      \"tag\":{ \n" +
            "        \"type\": \"keyword\", \n" +
            "        \"copy_to\": \"all\"\n" +
            "      },\n" +
            "      \"storeName\":{\n" +
            "        \"type\": \"text\",\n" +
            "        \"analyzer\": \"ik_smart\", \n" +
            "        \"copy_to\": \"all\"\n" +
            "      },\n" +
            "      \"filePath\":{\n" +
            "        \"type\": \"keyword\"\n" +
            "      },\n" +
            "      \"star\": {\n" +
            "        \"type\": \"double\"\n" +
            "      },\n" +
            "      \"ad_status\": {\n" +
            "        \"type\": \"boolean\"\n" +
            "      },\n" +
            "      \"ad_weight\":{\n" +
            "        \"type\": \"integer\"\n" +
            "      }\n" +
            "    }\n" +
            "  }\n" +
            "}";
    @Autowired
    ESConnection esConnection;
    @Autowired
    ElasticSearchInitProductMapper elasticSearchInitProductMapper;

    @Test
    void testCreateIndex() throws IOException {
        DeleteIndexRequest deleteRequest = new DeleteIndexRequest("shopping");
        GetIndexRequest getRequest = new GetIndexRequest("shopping");

        try (RestHighLevelClient client = esConnection.getClient()) {
            // 2. 发起请求
            if (client.indices().exists(getRequest, RequestOptions.DEFAULT)) {
                System.out.println("索引已存在，删除索引~");
                client.indices().delete(deleteRequest, RequestOptions.DEFAULT);
            }
            System.out.println("进行索引创建~");
            CreateIndexRequest createIndexRequest = new CreateIndexRequest("shopping");
            // 2. 请求参数，MAPPING_TEMPLATE是静态常量字符串，内容是创建索引库的DSL语句({...})
            createIndexRequest.source(indexCreateString, XContentType.JSON);
            // 3. 发起请求 indices()为获取对索引库操作的API create为创建索引库
            client.indices().create(createIndexRequest, RequestOptions.DEFAULT);
            // 2. 发起请求
            if (client.indices().exists(getRequest, RequestOptions.DEFAULT)) {
                System.out.println("索引创建成功~");
            } else {
                System.out.println("索引未创建成功~");
            }
        }
    }

    @Test
    void testInitES() throws IOException {
        List<ElasticSearchProductPO> productList;
        int begin = 0;
        String pattern = "\\s";
        String pattern2 = "\\\"|\\\\";
        while (!(productList = (elasticSearchInitProductMapper.getProductList(begin, 500))).isEmpty()) {
            System.out.println(begin);
            begin += 500;
            for (ElasticSearchProductPO product : productList) {
                if (product.getStatus() != 1) {
                    break;
                }
                String JSON_DOCUMENT = "{\n" + "  \"productId\": " + product.getProductId() +
                        ",\n" + "  \"title\":\"" + product.getTitle().replaceAll(pattern, " ").replaceAll(pattern2, "\\\\$0")
                        + "\",\n" + "  \"price\":\"" + product.getPrice()
                        + "\",\n" + "  \"tag\":\"" + product.getTag()
                        + "\",\n" + "  \"storeName\":\"" + product.getStoreName().replaceAll(pattern, " ").replaceAll(pattern2, "\\\\$0")
                        + "\",\n" + "  \"filePath\":\"" + product.getFilePath()
                        + "\",\n" + "  \"star\":\"" + product.getStar() + "\",\n"
                        + "  \"ad_status\":false,\n" + "  \"ad_weight\":0\n" + "}";
                try (RestHighLevelClient client = esConnection.getClient()) {
                    IndexRequest request = new IndexRequest("shopping").id(String.valueOf(product.getProductId()));
                    request.source(JSON_DOCUMENT, XContentType.JSON);
                    client.index(request, RequestOptions.DEFAULT);
                } catch (Exception e) {
                    System.out.println(e.getMessage());
                }
            }
        }
    }

    @Test
    void testSearch() throws IOException {
        try (RestHighLevelClient client = esConnection.getClient()) {
            String keyword = "华为";
            // 1.准备SearchRequest，指定索引库名称
            SearchRequest request = new SearchRequest("shopping");
            // 2.组织DSL参数(一般只修改这个部分)
            FunctionScoreQueryBuilder functionScoreQueryBuilder = QueryBuilders.functionScoreQuery(QueryBuilders.matchQuery("all", keyword), new FunctionScoreQueryBuilder.FilterFunctionBuilder[]{new FunctionScoreQueryBuilder.FilterFunctionBuilder(ScoreFunctionBuilders.fieldValueFactorFunction("star")  //算分函数

            ), new FunctionScoreQueryBuilder.FilterFunctionBuilder(QueryBuilders.termQuery("ad_status", "true"), ScoreFunctionBuilders.fieldValueFactorFunction("ad_weight") //算分函数
            )}).boostMode(CombineFunction.MULTIPLY);
            request.source().query(functionScoreQueryBuilder);
            //分页
            request.source().from(0).size(10);
            // 3.发送请求
            SearchResponse response = client.search(request, RequestOptions.DEFAULT);
            // 4.解析结果
            SearchHits searchHits = response.getHits();
            // 查询结果总条数
            long total = searchHits.getTotalHits().value;
            // 查询结果数组
            SearchHit[] hits = searchHits.getHits();
            for (SearchHit hit : hits) {
                String json = hit.getSourceAsString();
//                System.out.println(hit.getScore() + " " + json);
            }
        }
    }

    @Autowired
    ElasticSearchMapper elasticSearchMapper;

    @Test
    void testESMapper(){
        System.out.println(elasticSearchMapper.pushProductFromDatabase(4));
    }


}
